<?php

/**
 * Contains a class to display /user/profile.php.
 *
 * PHP Version 5
 *
 * @category BuyLocal
 * @package  BuyLocal
 * @author   Kevin Fodness <kevin.fodness@gmail.com>
 * @author   Mike Pennisi <mpennisi@andrew.cmu.edu>
 * @author   Aaron Ryden <aryden@gmail.com>
 * @author   Spencer Hakim <hakims@rpi.edu>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://code.google.com/p/buylocalopensourcerensselaer/
 */

/** @uses valueOf For safe handling of arrays. */
require_once 'function_valueof.php';

/** @uses validEmail To check email address validity. */
require_once 'function_validemail.php';
 
/**
 * A class to display /user/profile.php.
 *
 * @category BuyLocal
 * @package  BuyLocal
 * @author   Kevin Fodness <kevin.fodness@gmail.com>
 * @author   Mike Pennisi <mpennisi@andrew.cmu.edu>
 * @author   Aaron Ryden <aryden@gmail.com>
 * @author   Spencer Hakim <hakims@rpi.edu>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://code.google.com/p/buylocalopensourcerensselaer/
*/ 
class PageUserProfile extends Page
{
    /**
     * State variable for whether or not to update the user info.
     *
     * @access private
     * @var bool
     */
    private $_updateInfo;
    
    /**
     * State variable for whether or not to print the add phone number form.
     *
     * @access private
     * @var bool
     */
    private $_addPhoneForm;
    
    /**
     * State variable for whether or not to process a phone number addition.
    *
     * @access private
     * @var bool
     */
    private $_addPhone;
    
    /**
     * State variable for whether or not to process a phone number update.
     *
     * @access private
     * @var bool
     */
    private $_updatePhone;
    
    /**
     * State variable for whether or not to process an account deletion.
     *
     * @access private
     * @var bool
     */
    private $_deleteAccount;
    
    /**
     * A variable to contain an error message to be displayed.
     *
     * @access public
     * @var string
     */
    public $error;
    
    /**
     * Constructor function.  Calls the parent constructor and sets the title.
     */
    public function __construct()
    {
        parent::__construct();
        parent::setTitle('User Profile');
        
        /** Determines state. */
        $this->_deleteAccount = (valueOf($_GET, 'action') == 'deleteaccount');
        $this->_updatePhone   = (valueOf($_GET, 'action') == 'updatephone');
        $this->_addPhoneForm  = (valueOf($_GET, 'action') == 'addphone');
        if (count($_POST) > 0) {
            $this->_updateInfo = (
                (valueOf($_POST, 'name') != $this->user->name)
                || (valueOf($_POST, 'email') != $this->user->email)
                || (valueOf($_POST, 'zipcode') != $this->user->zip->zip)
                || (valueOf($_POST, 'password1') != '')
                || (valueOf($_POST, 'password2') != '')
            );
            $this->_addPhone = (valueOf($_POST, 'number') != '' 
                && valueOf($_POST, 'description') != ''
                && $this->_addPhoneForm);
        }
    }
    
    /**
     * Processes new phones
     *
     * @access private
     * @return null
     */
    private function _addPhoneAction()
    {
        /** Escape input and create object. */
        $number      = valueOf($_POST, 'number');
        $description = valueOf($_POST, 'description');
        $phone       = new Phone($number, $description);
        
        /** Error check. */
        $result = $this->db->addUserPhone($this->user, $phone);
        if ($result !== true) {
            $this->error = $result;
            return;
        }
        
        /** Reload User object. */
        $this->user = $this->db->getCurrentUser();
    }
    
    /**
     * Processes phone updates and deletions
     *
     * @access private
     * @return null
     */
    private function _updatePhoneAction()
    {
        foreach ($this->user->phoneNumbers as $phone) {
            $newNum = valueOf(
                $_POST,
                'phone_' . encode($phone->number) . '_'
                . encode($phone->description)
            );
            
            if (empty($newNum)) {
                $result = $this->db->deleteUserPhone($this->user, $phone);
                if ($result !== true) {
                    $this->error = $result;
                    return;
                }
                
            } else {                
                $newPhone         = clone $phone;
                $newPhone->number = $newNum;
                
                $result = $this->db->updateUserPhone($this->user, $newPhone);
                if ($result !== true) {
                    $this->error = $result;
                    return;
                }
            }
        }
        $this->user = $this->db->getCurrentUser();
    }
    
    /**
     * Deletes account
     *
     * @access private
     * @return null
     */
    private function _deleteAccountAction()
    {
        /** Verifiy input. */
        $result = $this->db->deleteUserAccount($this->user);
        if ($result !== true) {
            $this->error = $result;
        }
        
        /** Logout and send to homepage. */
        $this->db->deleteSessionById($_SESSION['sessionid']);
        $_SESSION['sessionid'] = '';
        header('Location: ' . BASE_URL);
    }
    
    /**
     * Function to print the edit form.
     *
     * @access private
     * @return null
     */
    private function _printEditForm()
    {
        if ($this->error != '') {
            printError($this->error, 1);
        }
        echo ' <form method="post" action="">', "\n",
            '  <div>', "\n",
            '   <label for="name">Name:</label>', "\n",
            '   <input type="text" name="name" id="name" ',
            'value="', encode($this->user->name), '" />', "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <label for="email">Email Address:</label>', "\n",
            '   <input type="text" name="email" id="email" ',
            'value="', encode($this->user->email), '" />', "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <label for="zipcode">Zip Code:</label>', "\n",
            '   <input type="text" name="zipcode" id="zipcode" ',
            'value="', $this->user->zip->zip, '" />', "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <label for="oldpassword">Old Password:</label>', "\n",
            '   <input type="password" name="oldpassword" id="oldpassword" />', 
            "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <label for="password1">New Password:</label>', "\n",
            '   <input type="password" name="password1" id="password1" />', 
            "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <label for="password2">New Password Again:</label>', "\n",
            '   <input type="password" name="password2" id="password2" />', 
            "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <input type="submit" class="button" value="Update" />', "\n",
            '  </div>', "\n",
            ' </form>', "\n", 
            ' <h2>Phone Numbers</h2>', "\n",
            ' <p class="centered">', "\n",
            '  <a href="?action=addphone">Add Phone Number</a>', "\n",
            ' </p>', "\n",
            ' <form method="post" action="?action=updatephone">', "\n";
        
        foreach ($this->user->phoneNumbers as $phone) {
            echo '  <div>', "\n",
                '   <label for="phone_', encode($phone->number), '">',
                encode($phone->description), ':</label>', "\n",
                '   <input type="text" name="phone_', encode($phone->number),
                '_', encode($phone->description), '" ',
                'id="phone_', encode($phone->number),
                '_', encode($phone->description), '" ',
                'value="', encode($phone->number), '" />', "\n",
                '  </div>', "\n";
        }
        
        echo '  <p class="centered">', "\n",
            '   <span style="font-size:10px">(Leave numbers blank',
            ' to delete them)</span><br />', "\n",
            '   <input type="submit" class="button"',
            ' value="Update Phones" />', "\n",
            '  </p>', "\n",
            ' </form>', "\n",
            ' <h2>Delete Account</h2>', "\n",
            ' <p class="centered">', "\n",
            '  <a href="?action=deleteaccount" onclick="return',
            ' confirm(\'Are you sure you wish to delete your account?\');">',
            'Delete My Account</a>', "\n",
            ' </p>', "\n";
    }
    
    /**
     * Function to print the add phone form.
     *
     * @access private
     * @return null
     */
    private function _printAddPhoneForm()
    {
        if ($this->error != '') {
            printError($this->error, 1);
        }
        echo ' <form method="post">', "\n",
            '  <div>', "\n",
            '   <label for="description">New Number Description:</label>', "\n",
            '   <input type="text" name="description" id="description"',
            ' value="', valueOf($_POST, 'description'), '" />', 
            "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <label for="number">New Number:</label>', "\n",
            '   <input type="text" name="number" id="number"',
            ' value="', valueOf($_POST, 'number'), '" />', 
            "\n",
            '  </div>', "\n",
            '  <div>', "\n",
            '   <input type="submit" class="button" value="Add Phone" />', "\n",
            '  </div>', "\n",
            ' </form>', "\n";
    }
    
    /**
     * Processes account update.
     *
     * @access private
     * @return null
     */
    private function _update()
    {
        $name      = valueOf($_POST, 'name');
        $email     = valueOf($_POST, 'email');
        $zipcode   = valueOf($_POST, 'zipcode');
        $oldpass   = valueOf($_POST, 'oldpassword');
        $password1 = valueOf($_POST, 'password1');
        $password2 = valueOf($_POST, 'password2');
        $oldUser   = $this->db->getCurrentuser();
        
        /** Determines validity of password data. */
        if ($password1 != $password2) {
            $this->error = 'The passwords provided do not match.';
            return;
        }
        if (empty($oldpass) && !empty($password1)) {
            $this->error = 'You must provide the old password to change it.';
            return;
        }
        
        /** Try to update password. */
        if (!empty($password1) && !empty($oldpass)) {
            if ($this->db->updateUserPassword($oldUser, $oldpass, $password1)!==true
            ) {
                $this->error = 'Old password is not valid,'
                . ' cannot set new password.';
                return;
            }
        }
        
        /** Build new user object by cloning old object. */
        $newUser        = clone $oldUser;
        $newUser->name  = $name;
        $newUser->email = $email;
        $newUser->zip   = $this->db->getZipByZip($zipcode);
        
        /** Error check. */
        $result = $this->db->updateUserInfo($oldUser, $newUser);
        if ($result !== true) {
            $this->error = $result;
        }
        
        /** Reload User object. */
        $this->user = $this->db->getCurrentUser();
    }
    
    /**
     * Function to display the page.
     *
     * @access public
     * @return null
     */
    public function display()
    {
        if ($this->_deleteAccount) {
            $this->_deleteAccountAction();
        }
        parent::printHeader();
        if ($this->user->role == R_GUEST) {
            echo 'Please <a title="Click to login" href="',
            RELATIVE_PATH, 'login.php">login</a> first.';
        
        } elseif ($this->_addPhone) {
            $this->_addPhoneAction();
            $this->_printEditForm();
        
        } elseif ($this->_addPhoneForm) {
            $this->_printAddPhoneForm();
            
        } elseif ($this->_updatePhone) {
            $this->_updatePhoneAction();
            $this->_printEditForm();
            
        } elseif ($this->_updateInfo) {
            $this->_update();
            $this->_printEditForm();
        
        } else {
            $this->_printEditForm();
        }
        parent::printFooter();
    }
}

?>